/*
 * Copyright 2002-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction;

/**
 * Interface that specifies an API to programmatically manage transaction
 * savepoints in a generic fashion. Extended by TransactionStatus to
 * expose savepoint management functionality for a specific transaction.
 *
 * <p>Note that savepoints can only work within an active transaction.
 * Just use this programmatic savepoint handling for advanced needs;
 * else, a subtransaction with PROPAGATION_NESTED is preferable.
 *
 * <p>This interface is inspired by JDBC 3.0's Savepoint mechanism
 * but is independent from any specific persistence technology.
 *
 * @author Juergen Hoeller
 * @since 1.1
 * @see TransactionStatus
 * @see TransactionDefinition#PROPAGATION_NESTED
 * @see java.sql.Savepoint
 */
/*
1. 总结
SavepointManager 是 Spring 框架中用于管理事务保存点（savepoint）的接口
提供了创建、回滚到和释放保存点的标准化方法
支持在事务中进行细粒度的回滚控制，实现嵌套事务的功能
2. 内部成员解释
方法说明：
	Object createSavepoint() 创建一个新的保存点，返回一个保存点对象
	void rollbackToSavepoint(Object savepoint)  将事务回滚到指定的保存点
	void releaseSavepoint(Object savepoint)  显式释放指定的保存点
3. 类与接口关系
SavepointManager (接口)
└── TransactionStatus (接口)
    ├── AbstractTransactionStatus (抽象类)
    │   ├── SimpleTransactionStatus (具体类)
    │   └── DefaultTransactionStatus (具体类)
    └── JdbcTransactionObjectSupport (具体类)
	关系说明：
		SavepointManager 接口被 TransactionStatus 接口继承，使得事务状态对象能够提供保存点管理功能
		AbstractTransactionStatus 是 TransactionStatus 的抽象实现，提供了保存点管理的基本实现
		SimpleTransactionStatus 和 DefaultTransactionStatus 是具体的事务状态实现类
		JdbcTransactionObjectSupport 是 JDBC 事务对象支持类，实现了 SavepointManager 接口
	与其他类的区别：
		TransactionStatus：表示事务的状态，包含保存点管理功能
		TransactionDefinition：定义事务的属性，如隔离级别、传播行为等
		PlatformTransactionManager：事务管理器，负责事务的开始、提交和回滚
4. 使用场景
	嵌套事务处理：当需要在一个事务中执行多个独立的操作，且希望某些操作失败时只回滚部分操作
	复杂业务逻辑：在复杂的业务流程中，需要对不同阶段的操作进行独立的回滚控制
	数据一致性维护：确保在发生错误时，只有受影响的部分数据被回滚，其他数据保持一致
5. 实际代码应用示例
// 示例：使用 SavepointManager 进行嵌套事务处理
public class SavepointExample {

    @Autowired
    private PlatformTransactionManager transactionManager;

    public void processComplexOperation() {
        TransactionStatus status = null;
        try {
            // 开始事务
            status = transactionManager.getTransaction(new DefaultTransactionDefinition());
            // 执行第一个操作
            performFirstOperation();
            // 创建保存点
            Object savepoint = status.createSavepoint();
            // 执行第二个操作
            performSecondOperation();
            // 如果第二个操作成功，提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            // 如果第二个操作失败，回滚到保存点
            if (status != null && status.hasSavepoint()) {
                status.rollbackToSavepoint();
                status.releaseSavepoint();
            }
            // 提交事务，第一个操作保留
            transactionManager.commit(status);
        }
    }
}

 */
public interface SavepointManager {

	/**
	 * Create a new savepoint. You can roll back to a specific savepoint
	 * via {@code rollbackToSavepoint}, and explicitly release a savepoint
	 * that you don't need anymore via {@code releaseSavepoint}.
	 * <p>Note that most transaction managers will automatically release
	 * savepoints at transaction completion.
	 * @return a savepoint object, to be passed into
	 * {@link #rollbackToSavepoint} or {@link #releaseSavepoint}
	 * @throws NestedTransactionNotSupportedException if the underlying
	 * transaction does not support savepoints
	 * @throws TransactionException if the savepoint could not be created,
	 * for example because the transaction is not in an appropriate state
	 * @see java.sql.Connection#setSavepoint
	 */
	Object createSavepoint() throws TransactionException;

	/**
	 * Roll back to the given savepoint.
	 * <p>The savepoint will <i>not</i> be automatically released afterwards.
	 * You may explicitly call {@link #releaseSavepoint(Object)} or rely on
	 * automatic release on transaction completion.
	 * @param savepoint the savepoint to roll back to
	 * @throws NestedTransactionNotSupportedException if the underlying
	 * transaction does not support savepoints
	 * @throws TransactionException if the rollback failed
	 * @see java.sql.Connection#rollback(java.sql.Savepoint)
	 */
	void rollbackToSavepoint(Object savepoint) throws TransactionException;

	/**
	 * Explicitly release the given savepoint.
	 * <p>Note that most transaction managers will automatically release
	 * savepoints on transaction completion.
	 * <p>Implementations should fail as silently as possible if proper
	 * resource cleanup will eventually happen at transaction completion.
	 * @param savepoint the savepoint to release
	 * @throws NestedTransactionNotSupportedException if the underlying
	 * transaction does not support savepoints
	 * @throws TransactionException if the release failed
	 * @see java.sql.Connection#releaseSavepoint
	 */
	void releaseSavepoint(Object savepoint) throws TransactionException;

}
